package emulator;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.UIManager;

import emulator.assembler.Assembler;
import emulator.hardware.bits.BitCollector;
import emulator.hardware.bits.BitCollectorAndStrategy;
import emulator.hardware.bus.FloppyBus;
import emulator.hardware.clock.Clock;
import emulator.hardware.clock.ClockImpl2;
import emulator.hardware.io.Via6522;
import emulator.hardware.memory.MemoryBlock;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.shell.DebugShell;
import emulator.shell.GUI.ShellUI;

public class Vc1541Main
{
	/**
	 * @param args
	 * @throws EmulatorException 
	 */
	public static void main(String[] args) throws Exception
	{
		UIManager.setLookAndFeel(
				UIManager.getSystemLookAndFeelClassName());
		
		EmulatorConfig config = new EmulatorConfig();
		
		runEmulator(args, config);
		
	}

	public static void runEmulator(String[] args, EmulatorConfig config) throws IOException, FileNotFoundException
	{
		MemoryBlock memory = new MemoryBlock(65536);

		memory.loadFromStream(new FileInputStream("data\\1541-c000.325302-01.bin"), 0xC000, 0x2000);
		memory.loadFromStream(new FileInputStream("data\\1541-e000.901229-03.bin"), 0xE000, 0x2000);

		Assembler assembler = new Assembler();

		Cpu6502 cpu = new Cpu6502();
		Via6522 via1 = new Via6522();
		Via6522 via2 = new Via6522();

		FloppyBus bus = new FloppyBus(memory, via1, via2);

		Clock clock = new ClockImpl2();
		
		BitCollector irq_in = new BitCollector(2, cpu.getIrqIn(), new BitCollectorAndStrategy());
		via1.attach(clock, irq_in.getBitAt(0));
		via2.attach(clock, irq_in.getBitAt(1));

		cpu.attach(bus, clock);
		
		ShellUI ui = new ShellUI("Vic1541", cpu, memory, bus, clock);
		ui.setAssembler(assembler);
		ui.setVias(via1, via2);

		DebugShell shell = new DebugShell(ui.createIn(), ui.createOut(), ui.createErr());
		shell.init(cpu, bus);
		shell.setMemory(memory);
		shell.setMemoryBlock(memory);
		shell.setAssembler(assembler);
		if (args.length > 0)
			shell.setStartScript(args[0]);
		shell.start();
		
		if (config.isEnablePortLogging())
			ui.initPortStateHistory();
		
		via1.start();
		via2.start();
		cpu.start();
	}
}
